using FluentMigrator;

namespace AuthService.Infrastructure.Migrations;

/// <summary>
/// 创建用户表的数据库迁移
/// 版本号：20241214001 (格式：YYYYMMDDNNN)
/// 包含用户基本信息、认证信息和审计字段
/// 支持多租户架构和软删除模式
/// </summary>
[Migration(20241214001)] // 迁移版本号，FluentMigrator使用此版本号来跟踪迁移状态
public class CreateUsersTable : Migration
{
    /// <summary>
    /// 执行向上迁移 - 创建Users表及其索引
    /// 当执行 MigrateUp() 时会调用此方法
    /// </summary>
    public override void Up()
    {
        // 使用FluentMigrator的流式API创建表
        Create.Table("Users")
            // === 基础标识字段 ===
            .WithColumn("Id").AsGuid().PrimaryKey("PK_Users") // 主键，使用GUID避免ID冲突
            .WithColumn("Username").AsString(50).NotNullable().Unique("UQ_Users_Username") // 用户名，唯一约束
            .WithColumn("Email").AsString(255).NotNullable().Unique("UQ_Users_Email") // 邮箱，唯一约束
            .WithColumn("PasswordHash").AsString(255).NotNullable() // 密码哈希值，不存储明文密码
            .WithColumn("PasswordSalt").AsString(255).NotNullable() // 密码盐值，增强安全性

            // === 用户个人信息字段 ===
            .WithColumn("DisplayName").AsString(100).Nullable() // 显示名称，可为空
            .WithColumn("AvatarUrl").AsString(500).Nullable() // 头像URL，可为空
            .WithColumn("PhoneNumber").AsString(20).Nullable() // 手机号码，可为空

            // === 验证状态字段 ===
            .WithColumn("IsEmailVerified").AsBoolean().NotNullable().WithDefaultValue(false) // 邮箱验证状态
            .WithColumn("IsPhoneVerified").AsBoolean().NotNullable().WithDefaultValue(false) // 手机验证状态
            .WithColumn("IsActive").AsBoolean().NotNullable().WithDefaultValue(true) // 账户激活状态
            .WithColumn("IsLocked").AsBoolean().NotNullable().WithDefaultValue(false) // 账户锁定状态
            .WithColumn("LockoutEnd").AsDateTime().Nullable() // 锁定结束时间，可为空表示永久锁定或未锁定
            .WithColumn("FailedLoginAttempts").AsInt32().NotNullable().WithDefaultValue(0) // 失败登录尝试次数

            // === 登录信息字段 ===
            .WithColumn("LastLoginAt").AsDateTime().Nullable() // 最后登录时间
            .WithColumn("LastLoginIp").AsString(45).Nullable() // 最后登录IP，45字符支持IPv6

            // === 权限字段（JSON格式存储） ===
            .WithColumn("Roles").AsString(2000).NotNullable().WithDefaultValue("[]") // 用户角色，JSON数组格式
            .WithColumn("Permissions").AsString(2000).NotNullable().WithDefaultValue("[]") // 用户权限，JSON数组格式

            // === 扩展字段 ===
            .WithColumn("Metadata").AsString(4000).Nullable() // 元数据，JSON格式存储扩展信息
            .WithColumn("TenantId").AsString(50).Nullable() // 租户ID，支持多租户架构

            // === 审计字段（用于跟踪数据变更） ===
            .WithColumn("CreatedAt").AsDateTime().NotNullable().WithDefaultValue(SystemMethods.CurrentUTCDateTime) // 创建时间，使用UTC时间
            .WithColumn("UpdatedAt").AsDateTime().NotNullable().WithDefaultValue(SystemMethods.CurrentUTCDateTime) // 更新时间，使用UTC时间
            .WithColumn("CreatedBy").AsString(50).Nullable() // 创建者
            .WithColumn("UpdatedBy").AsString(50).Nullable() // 更新者
            .WithColumn("IsDeleted").AsBoolean().NotNullable().WithDefaultValue(false) // 软删除标记
            .WithColumn("DeletedAt").AsDateTime().Nullable() // 删除时间
            .WithColumn("DeletedBy").AsString(50).Nullable(); // 删除者

        // === 创建数据库索引以提高查询性能 ===

        // 邮箱索引 - 用于登录验证和用户查找
        Create.Index("IX_Users_Email")
            .OnTable("Users")
            .OnColumn("Email")
            .Ascending(); // 升序排列，适合等值查询和范围查询

        // 用户名索引 - 用于登录验证和用户查找
        Create.Index("IX_Users_Username")
            .OnTable("Users")
            .OnColumn("Username")
            .Ascending();

        // 租户ID索引 - 用于多租户数据隔离查询
        Create.Index("IX_Users_TenantId")
            .OnTable("Users")
            .OnColumn("TenantId")
            .Ascending();

        // 状态复合索引 - 用于查询活跃且未删除的用户
        Create.Index("IX_Users_IsActive_IsDeleted")
            .OnTable("Users")
            .OnColumn("IsActive").Ascending()
            .OnColumn("IsDeleted").Ascending();

        // 创建时间索引 - 用于按创建时间排序查询（最新的在前）
        Create.Index("IX_Users_CreatedAt")
            .OnTable("Users")
            .OnColumn("CreatedAt")
            .Descending(); // 降序排列，最新记录在前

        // 最后登录时间索引 - 用于查询最近活跃用户
        Create.Index("IX_Users_LastLoginAt")
            .OnTable("Users")
            .OnColumn("LastLoginAt")
            .Descending(); // 降序排列，最近登录的在前

        // 多租户场景的复合索引 - 优化多租户环境下的用户查询
        // 这个索引特别适合查询：特定租户下的活跃用户
        Create.Index("IX_Users_TenantId_IsActive_IsDeleted")
            .OnTable("Users")
            .OnColumn("TenantId").Ascending() // 先按租户分组
            .OnColumn("IsActive").Ascending() // 再按活跃状态
            .OnColumn("IsDeleted").Ascending(); // 最后按删除状态
    }

    /// <summary>
    /// 执行向下迁移 - 删除Users表
    /// 当执行回滚操作时会调用此方法
    /// 注意：这会删除整个表及其所有数据，请谨慎使用
    /// </summary>
    public override void Down()
    {
        // 删除整个Users表
        // FluentMigrator会自动处理相关的索引和约束的删除
        Delete.Table("Users");
    }
}
